//----------DDDummyDAQ.cc----------//

#include "DDVDAQ.hh"
#include "DDDummyDAQ.hh"
#include <math.h>
#include <fstream>
#include <iostream>
#include <assert.h>

//-----config-----//
//===sets and gets===//
int DDDummyDAQ::dummy_config::add_channel(int channel_arg)
{
  if (channel_arg<=4)
    {
      channels.insert(channel_arg);
    }
  
  else
    {
      cout << "CHANNEL OUT OF RANGE. DUMMY HAS 4 CHANNELS" << endl;
      return (-1);
    }	
}

int DDDummyDAQ::dummy_config::remove_channel(int channel_arg)
{
  if (channel_arg<=4)
    {
      channels.erase(channel_arg);
    }
  
  else
    {
      cout << "CHANNEL OUT OF RANGE. DUMMY HAS 4 CHANNELS" << endl;
      return (-1);
    }	
}

void DDDummyDAQ::dummy_config::set_samples_per_trace(unsigned int samples_per_trace_arg)
{
  samples_per_trace = samples_per_trace_arg;
}

int DDDummyDAQ::dummy_config::get_samples_per_trace(void)
{
  return samples_per_trace;
}
//=========//

void DDDummyDAQ::dummy_config::load_config(void)
{
  // This function reads in our configuration file.
  // It might be good to allow the user to send in a config file instead of a hard coded filename.
  ifstream config_file("dummy.config");
  
  string value_name;
  
  config_file >> value_name >> base_filename;
  config_file >> value_name >> output_type;
  
  int channel;
  
  while (1)
    {
	config_file >> value_name;
	if(value_name.compare("channel:") != 0) break;
	config_file >> channel;
	add_channel(channel);
	std::cout << "Added channel: " << channel << std::endl;
    };
  
  config_file >> num_traces_requested;
  
  config_file >> value_name >> samples_per_trace;
  
  config_file.close();
}

//----header----//
void DDDummyDAQ::dummy_header::write_header(fstream* data_file, set<int> channels)
{
	if ( data_file ) 
	{
		data_file->write( reinterpret_cast<char*>( &num_traces ), sizeof num_traces );
		data_file->write( reinterpret_cast<char*>( &num_channels ), sizeof num_channels );
		set<int>::iterator channel;	
		unsigned int current_channel;
		for(channel=channels.begin();channel!=channels.end();++channel)
		{
			current_channel = *channel;
			data_file->write( reinterpret_cast<char*>( &current_channel ), sizeof current_channel );
			data_file->write( reinterpret_cast<char*>( &samples_per_trace[*channel] ), sizeof samples_per_trace[*channel] );
			data_file->write( reinterpret_cast<char*>( &bits_per_sample[*channel] ), sizeof bits_per_sample[*channel] );
			data_file->write( reinterpret_cast<char*>( &time_per_sample[*channel] ), sizeof time_per_sample[*channel] );
			data_file->write( reinterpret_cast<char*>( &trigger_offset[*channel] ), sizeof trigger_offset[*channel] );
			data_file->write( reinterpret_cast<char*>( &volts_per_sample[*channel] ), sizeof volts_per_sample[*channel] );
			data_file->write( reinterpret_cast<char*>( &voltage_offset[*channel] ), sizeof voltage_offset[*channel] );
		}
	}
}


//----instrument----//

void DDDummyDAQ::initialize(void)
{
  
  cout << "DDDummyDAQ::Initialize" << endl;

  std::set<int>* my_channels = config.get_channels();
  std::set<int>::iterator channel;
  
  //Do stuff here to initialize instrument
  //Set config_dependent header parameters
  header.set_num_traces( config.get_num_traces_requested() );
  cout << "set num traces" << endl;
  header.set_num_channels( my_channels->size() );

  // for(channel=(config.get_channels()).begin();channel!=(config.get_channels()).end();++channel)
  //  {
  //    cout << "ch:" << *channel << endl;
  //  }	
  // cout << "done 1st loop" << endl;

  for(channel= (*my_channels).begin();channel!=(*my_channels).end();++channel)
    {
      cout << "in channel loop" << endl;
      //Set config_dependent header parameters
      cout << "CHANNEL" << endl;
      header.set_samples_per_trace(*channel,config.get_samples_per_trace());
      
      //Read header parameters from instrument

      double v_range;
      double v_sample;
      
      header.set_bits_per_sample(*channel,8);
      header.set_time_per_sample(*channel,1);
      header.set_trigger_offset(*channel,0);	
      
      v_range = 2.0;
      v_sample = v_range/(pow(2,header.get_bits_per_sample(*channel))-1);
      header.set_volts_per_sample(*channel,v_sample);
      
      header.set_voltage_offset(*channel,0);	
    }
  cout << "finished channel loop" << endl;
  cout << "" << endl;
}

void DDDummyDAQ::acquire_data(void)
{
  cout << "in acq dat" << endl;

  initialize();
  cout << "finished init" << endl;
  //fstream* data_file = new fstream((config.get_base_filename())+".dat", ios::binary );
  fstream* data_file = new fstream((config.get_base_filename()).c_str(), ios::out | ios::binary );
  
  cout << "opened datafile" << endl;
  header.write_header(data_file, *config.get_channels());
  cout << "finished write_header" << endl;
  
  double voltage;
  short int adc_count;
  
  double v_range=2.0;
  std::set<int>* my_channels = config.get_channels();
  std::set<int>::iterator channel;
  
  for(int trace=0; trace<config.get_num_traces_requested();trace++)
    {
      if (trace%1000==0) cout << "Dummy trace " << trace << std::endl;
      //cout << "TRACEROO" << endl;
      for(channel=(*my_channels).begin();channel!=(*my_channels).end();++channel)
	{
	  //	cout << "CHANNELROO" << endl;
	  //cout << "CHANNEL: " << *channel << endl;
	  
	  for(int sample=0; sample<header.get_samples_per_trace(*channel); sample++)
	    {
	      //		cout << "time_per_samp" << header.get_time_per_sample(*channel) << endl;
	      //cout << "samps_per_trace" << header.get_samples_per_trace(*channel) << endl;
	      
	      voltage = sin((header.get_time_per_sample(*channel)) * sample * trace) + *channel + header.get_voltage_offset(*channel);
	      //		cout << "VOLTAGE: " << voltage << endl;
	      adc_count = (voltage - header.get_voltage_offset(*channel) + v_range/2) / header.get_volts_per_sample(*channel);
	      
	      if ((*channel == 1)) adc_count  = 3;
	      data_file->write( reinterpret_cast<char*>( &adc_count ), sizeof adc_count );
	    }	
	  
	}
    }
  
  cout << "finished iterating" << endl;
  
  data_file->close();
  
  cout << "closed data file" << endl;
	
}	


//----------DDDummyDAQ.cc----------//
